package com.hcss.common.redis.base.impl;

import com.hcss.common.redis.base.RedisZSetDao;
import com.hcss.common.util.ReflectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * @描述: redis ZSet类型数据操作Dao接口实现
 * @作者: xuqian
 * @创建日期: 2018-08-07 14:12
 * @公司 浙江鸿程计算机系统有限公司
 */
@Repository("redisZSetDao")
public class RedisZSetDaoImpl<T> extends BaseRedisDaoImpl<T> implements RedisZSetDao<T> {
    private final ZSetOperations<String, T> zSetOperations;

    @Autowired
    public RedisZSetDaoImpl(RedisTemplate redisTemplate) {
        super(redisTemplate);
        this.zSetOperations = redisTemplate.opsForZSet();
    }

    @Override
    public void insert(String key, T value) {
        zSetOperations.add(key, value, 0);
    }

    @Override
    public T selectObject(String key) {
        return null;
    }

    @Override
    public ZSetOperations getZSetOperations() {
        return zSetOperations;
    }

    @Override
    public void insert(String key, T value, double score) {
        zSetOperations.add(key, value, score);
    }

    @Override
    public void insert(String key, Collection<T> data, String columnName) {
        Set<ZSetOperations.TypedTuple<T>> set = new LinkedHashSet<>(data.size());
        for (T temp : data) {
            Object score = ReflectUtil.getFieldValue(temp, columnName);
            set.add(new DefaultTypedTuple<>(temp, score == null ? 0 : Double.valueOf(score.toString())));
        }
        zSetOperations.add(key, set);
    }

    @Override
    public Set<T> selectAll(String key) {
        return zSetOperations.range(key, 0, -1);
    }

    @Override
    public Set<T> selectAllReverse(String key) {
        return zSetOperations.reverseRange(key, 0, -1);
    }

    @Override
    public Set<T> selectSet(String key, long start, long end) {
        return zSetOperations.range(key, start, end);
    }

    @Override
    public Set<T> selectSetReverse(String key, long start, long end) {
        return zSetOperations.reverseRange(key, start, end);
    }

    @Override
    public Set<T> selectByScore(String key, double min, double max) {
        return zSetOperations.rangeByScore(key, min, max);
    }

    @Override
    public Set<T> selectReverseByScore(String key, double min, double max) {
        return zSetOperations.reverseRangeByScore(key, min, max);
    }

    @Override
    public void delete(String key, T... values) {
        zSetOperations.remove(key, values);
    }

    @Override
    public void deleteAll(String key) {
        super.clear(key);
    }

    @Override
    public Set<T> getInterAndStore(String key1, String key2, String key3) {
        zSetOperations.intersectAndStore(key1, key2, key3);
        return selectAll(key3);
    }

    @Override
    public Set<T> getUnionAndStore(String key1, String key2, String key3) {
        zSetOperations.unionAndStore(key1, key2, key3);
        return selectAll(key3);
    }

    @Override
    public Long count(String key, double min, double max) {
        return zSetOperations.count(key, min, max);
    }

    @Override
    public Long size(String key) {
        return zSetOperations.size(key);
    }

    @Override
    public Long selectValueIndex(String key, T value) {
        return zSetOperations.rank(key, value);
    }

    @Override
    public Double selectValueScore(String key, T value) {
        return zSetOperations.score(key, value);
    }
}
